package cn.qianxun.meta.auth.api.service.impl;

import cn.qianxun.meta.auth.api.mapper.AuthApiInfoMapper;
import cn.qianxun.meta.auth.api.mapper.AuthAppApiRelaMapper;
import cn.qianxun.meta.auth.api.service.IAuthApiInfoService;
import cn.qianxun.meta.common.core.dto.ChangeStatusDTO;
import cn.qianxun.meta.common.core.dto.RowsData;
import cn.qianxun.meta.common.core.field.AbstractFieldAssert;
import cn.qianxun.meta.common.core.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import cn.qianxun.meta.auth.api.dto.AddAuthApiInfoDTO;
import cn.qianxun.meta.auth.api.dto.AuthApiInfoQueryDTO;
import cn.qianxun.meta.auth.api.dto.DistributionApiDTO;
import cn.qianxun.meta.auth.api.entity.AuthApiInfo;
import cn.qianxun.meta.auth.api.entity.AuthAppApiRela;
import cn.qianxun.meta.auth.api.vo.AuthApiInfoVO;
import cn.qianxun.meta.common.core.exception.ServiceException;
import cn.qianxun.meta.common.satoken.utils.LoginHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 认证API接口基本信息 服务实现类
 * </p>
 *
 * @author fuzhilin
 * @since 2023-09-12 01:41:24
 */
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class AuthApiInfoServiceImpl extends ServiceImpl<AuthApiInfoMapper, AuthApiInfo> implements IAuthApiInfoService {
    private final AuthAppApiRelaMapper authAppApiRelaMapper;

    @Override
    public RowsData<AuthApiInfoVO> selectApiInfoList(AuthApiInfoQueryDTO dto) {
        LambdaQueryWrapper<AuthApiInfo> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(dto.getApiName())) {
            wrapper.like(AuthApiInfo::getApiName, dto.getApiName());
        }
        if (StringUtils.isNotEmpty(dto.getApiUrl())) {
            wrapper.like(AuthApiInfo::getApiUrl, dto.getApiUrl());
        }
        if (StringUtils.isNotEmpty(dto.getApiMod())) {
            wrapper.eq(AuthApiInfo::getApiMod, dto.getApiMod());
        }
        if (StringUtils.isNotNull(dto.getApiStatus())) {
            wrapper.eq(AuthApiInfo::getApiStatus, dto.getApiStatus());
        }
        if (StringUtils.isNotNull(dto.getAppId()) && StringUtils.isNotNull(dto.getIsShare())) {
            if (!Arrays.asList(0, 1).contains(dto.getIsShare())) {
                throw new ServiceException("是否分配应用参数不正确");
            }
            List<Long> apiIds = authAppApiRelaMapper.selectList(new LambdaQueryWrapper<AuthAppApiRela>().eq(AuthAppApiRela::getAppId, dto.getAppId()).select(AuthAppApiRela::getApiId)).stream().distinct().map(AuthAppApiRela::getApiId).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(apiIds)) {
                if (0 == dto.getIsShare()) {
                    wrapper.notIn(AuthApiInfo::getId, apiIds);
                } else if ((1 == dto.getIsShare())) {
                    wrapper.in(AuthApiInfo::getId, apiIds);
                }
            } else {
                if ((1 == dto.getIsShare())) {
                    return new RowsData<>(new ArrayList<>(), 0L, 1);
                }
            }
        } else if (StringUtils.isNotNull(dto.getAppId())) {
            List<Long> apiIds = authAppApiRelaMapper.selectList(new LambdaQueryWrapper<AuthAppApiRela>().eq(AuthAppApiRela::getAppId, dto.getAppId()).select(AuthAppApiRela::getApiId)).stream().distinct().map(AuthAppApiRela::getApiId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(apiIds)) {
                return new RowsData<>(new ArrayList<>(), 0L, 1);
            }
            wrapper.in(AuthApiInfo::getId, apiIds);
        }
        wrapper.orderByAsc(AuthApiInfo::getOrderNum);
        try (Page<Object> page = PageHelper.startPage(dto.getPageNum(), dto.getPageSize())) {
            List<AuthApiInfoVO> list = baseMapper.selectVoList(wrapper, AuthApiInfoVO.class);
            return new RowsData<AuthApiInfoVO>(list, page.getTotal(), dto.getPageNum());
        }
    }

    @Override
    public void addApiInfo(AddAuthApiInfoDTO dto) {
        dto.setId(null);
        AuthApiInfo authApiInfo = new AuthApiInfo();
        BeanUtils.copyProperties(dto, authApiInfo);
        authApiInfo.setCreateBy(LoginHelper.getUserName());
        baseMapper.insert(authApiInfo);

    }

    @Override
    public void editApiInfo(AddAuthApiInfoDTO dto) {
        AbstractFieldAssert.isNull(dto.getId(), "应用id不能为空");
        AuthApiInfo authApiInfo = baseMapper.selectById(dto.getId());
        if (StringUtils.isNull(authApiInfo)) {
            throw new ServiceException("所修改数据不存在");
        }
        BeanUtils.copyProperties(dto, authApiInfo);
        baseMapper.updateById(authApiInfo);
    }

    @Override
    public AuthApiInfoVO details(Long id) {
        AbstractFieldAssert.isNull(id, "应用id不能为空");
        return baseMapper.selectVoById(id, AuthApiInfoVO.class);
    }

    @Override
    public void changeStatus(ChangeStatusDTO dto) {
        AuthApiInfo authApiInfo = baseMapper.selectById(dto.getBusinessId());
        if (StringUtils.isNull(authApiInfo)) {
            throw new ServiceException("未获取到应用信息");
        }
        authApiInfo.setApiStatus(Integer.valueOf(dto.getStatus()));
        baseMapper.updateById(authApiInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void distribution(DistributionApiDTO dto) {
        if (!CollectionUtils.isEmpty(dto.getApiIdList())) {
            if (1 == dto.getAddOrDel()) {
                authAppApiRelaMapper.delete(new LambdaQueryWrapper<AuthAppApiRela>().eq(AuthAppApiRela::getAppId, dto.getAppId()).in(AuthAppApiRela::getApiId, dto.getApiIdList()));
                List<AuthAppApiRela> apiRelaList = new ArrayList<>();
                for (Long apiId : dto.getApiIdList()) {
                    AuthAppApiRela appApiRela = new AuthAppApiRela();
                    appApiRela.setAppId(dto.getAppId());
                    appApiRela.setApiId(apiId);
                    apiRelaList.add(appApiRela);
                }
                authAppApiRelaMapper.insertBatch(apiRelaList);
            } else if (2 == dto.getAddOrDel()) {
                authAppApiRelaMapper.delete(new LambdaQueryWrapper<AuthAppApiRela>().eq(AuthAppApiRela::getAppId, dto.getAppId()).in(AuthAppApiRela::getApiId, dto.getApiIdList()));
            }

        }

    }
}
